package com.ywl.study.transaction.manager.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    //todo 现在默认是往所有channnel中都发送提交或者回滚命令，需要改成groupId匹配的所有channel
    private static ChannelGroup channelGroup=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    //事务组中的事务状态列表

    private static Map<String, List<String>> transactionTypeMap=new HashMap<>();

    //事务组中是否接受到结束的标志
    private static Map<String,Boolean> isEndMap=new HashMap<>();

    //事务组中应该有的事务个数
    private static Map<String,Integer> transactionCountMap=new HashMap<>();

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
       Channel channel=ctx.channel();
       channelGroup.add(channel);
    }

    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.info("netty server 接受数据："+msg.toString());
        JSONObject jsonObject= JSON.parseObject((String)msg);

        String command=jsonObject.getString("command");//create-创建 register-注册分支事务 commit-提交事务
        String groupId=jsonObject.getString("groupId");//事务组id
        String transactionType=jsonObject.getString("transactionType");//分支事务类型 commit-待提交 rollback--待回滚
        if("create".equals(command)){
            //开启全局事务
            transactionTypeMap.put(groupId,new ArrayList<>());
        }else if("add".equals(command)){
            //注册分支事务
            transactionTypeMap.get(groupId).add(transactionType);

        }else if("over".equals(command)){
            isEndMap.put(groupId,true);
            JSONObject result=new JSONObject();
            result.put("groupId",groupId);
                if(transactionTypeMap.get(groupId).contains("ROLLBACK")){
                    result.put("command","rollback");
                    sendMsg(result);
                }else{
                    result.put("command","commit");
                    sendMsg(result);
                }
        }
        super.channelRead(ctx, msg);
    }

    private void sendMsg(JSONObject result){
        for (Channel channel : channelGroup) {
            log.info("发送数据："+result.toString());
            channel.writeAndFlush(result.toJSONString());
        }
    }
}
